package  {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.math.Plane3D;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;
import org.papervision3d.core.math.Matrix3D
import org.papervision3d.view.stats.StatsView

import fr.seraf.wow.primitive.WSphere;
import fr.seraf.wow.core.WOWEngine;
import fr.seraf.wow.core.data.WVector;
import fr.seraf.wow.primitive.WBoundArea;

/**
* ...
* @author Exey Panteleev
*/
[ SWF( backgroundColor = '#000000', width = '800', height = '600', frameRate='120' ) ]
public class GITest extends BasicView {
	
	[Embed(source = '3334.jpg')]
	public var floorBitmap:Class; //Chess Pattern - Marble by Edu http://www.filterforge.com/filters/3334.html
	
	[Embed(source = '5378.jpg')]
	public var wallBitmap:Class;// Texture002 by ShortCircuit http://www.filterforge.com/filters/5378.html
	
	private static const PLANES_POSITION:Number3D = new Number3D(0, 0, 0)
	private static const PLANE_SIZE:uint = 512;
	
	private var plane1:Plane;
	private var plane2:Plane;
	private var plane3:Plane;
	
	private var colorSpot11:ColorSpotCaster;
	private var colorSpot12:ColorSpotCaster;
	private var colorSpot13:ColorSpotCaster;
	private var colorSpot21:ColorSpotCaster;
	private var colorSpot22:ColorSpotCaster;
	private var colorSpot23:ColorSpotCaster;
	private var colorSpot31:ColorSpotCaster;
	private var colorSpot32:ColorSpotCaster;
	private var colorSpot33:ColorSpotCaster;
	
	private var isDragging:Boolean;
	
	private var colorSphere1:Sphere;
	private var colorSphere2:Sphere;
	private var colorSphere3:Sphere;
	
	private var rotationCount:uint
	private var rotationRadian:Number
	
	private var pv3dObjects:Array = new Array();
	private var wowObjects:Array = new Array();

	//PHYSICS
	private var wow:WOWEngine;
	private var sphere01:WSphere;
	private var sphere02:WSphere;
	private var sphere03:WSphere;
	private var sphere04:WSphere;
	private var bound:WBoundArea
	
	public function GITest() {
		super(800, 600, false, false, "CAMERA3D");
		preparePv3d();
		initPhysics();
		createObjects();
		addListeners();
	}
	
	public function preparePv3d():void {
		stage.addChild(new StatsView(renderer));
		camera.x = 600
		camera.y=250
		camera.rotationY = -30
		camera.zoom =900
	}
	
	private function initPhysics():void{
		wow=new WOWEngine(.3);
		wow.collisionResponseMode = wow.SELECTIVE;
		wow.addMasslessForce(new WVector(0, -5, 0));
		
		sphere01 = new WSphere(PLANES_POSITION.x-100,PLANES_POSITION.y+300,PLANES_POSITION.z,50,false, .1, .8);
		wow.addParticle(sphere01);
		wowObjects.push(sphere01);
		
		sphere02 = new WSphere(PLANES_POSITION.x-150,PLANES_POSITION.y+325,PLANES_POSITION.z,50,false, .1, .8);
		wow.addParticle(sphere02);
		wowObjects.push(sphere02);
		
		sphere03 = new WSphere(PLANES_POSITION.x-200,PLANES_POSITION.y+310,PLANES_POSITION.z,50,false, .1, .8);
		wow.addParticle(sphere03);
		wowObjects.push(sphere03);
		
		bound = new WBoundArea(PLANE_SIZE,PLANE_SIZE,PLANE_SIZE);
		bound.setPosition(PLANES_POSITION.x,PLANES_POSITION.y+PLANE_SIZE*0.5,PLANES_POSITION.z);
		bound.elasticity=.6;
		bound.friction=0;
		wow.setBoundArea(bound);
	}
	
	public function createObjects():void {
		
		var colorMat1:ColorMaterial = new ColorMaterial(0x00FF00)
		colorMat1.doubleSided = true
		colorSphere1  = new Sphere(colorMat1, 50, 8, 8)
		scene.addChild(colorSphere1)
		pv3dObjects.push(colorSphere1);
		
		var colorMat2:ColorMaterial = new ColorMaterial(0x0000FF)
		colorMat2.doubleSided = true
		colorSphere2  = new Sphere(colorMat2, 50, 8, 8)
		scene.addChild(colorSphere2)
		pv3dObjects.push(colorSphere2);
		
		var colorMat3:ColorMaterial = new ColorMaterial(0xFF0000)
		colorMat3.doubleSided = true
		colorSphere3  = new Sphere(colorMat3, 50, 8, 8)
		scene.addChild(colorSphere3)
		pv3dObjects.push(colorSphere3);
		
		var floorBmp1:Bitmap = new floorBitmap() as Bitmap;
		var floorSprite1:Sprite  = new Sprite()
		floorSprite1.addChild(floorBmp1)
		var planeMat1:MovieMaterial = new MovieMaterial(floorSprite1, false, true, false, new Rectangle(0,0, PLANE_SIZE, PLANE_SIZE) );
		planeMat1.opposite = false
		plane1 = new Plane(planeMat1, PLANE_SIZE, PLANE_SIZE , 3, 3 )
		plane1.rotationX = -90;
		plane1.x = PLANES_POSITION.x
		plane1.y = PLANES_POSITION.y
		plane1.z = PLANES_POSITION.z
		scene.addChild(plane1)
		var p3d1:Plane3D = new Plane3D(new Number3D(0,1,0), new Number3D(plane1.x, plane1.y, plane1.z))
		colorSpot11 = new ColorSpotCaster(p3d1, Sprite(MovieMaterial(plane1.material).movie), 0x00ff00, 200, 200)
		colorSpot12 = new ColorSpotCaster(p3d1, Sprite(MovieMaterial(plane1.material).movie), 0x0000ff, 200, 200)
		colorSpot13 = new ColorSpotCaster(p3d1, Sprite(MovieMaterial(plane1.material).movie), 0xff0000, 200, 200)
		
		var wallBmp2:Bitmap = new wallBitmap() as Bitmap;
		var wallSprite2:Sprite  = new Sprite()
		wallSprite2.addChild(wallBmp2)
		var planeMat2:MovieMaterial = new MovieMaterial(wallSprite2, false, true, false, new Rectangle(0,0, PLANE_SIZE, PLANE_SIZE) );
		plane2 = new Plane(planeMat2, PLANE_SIZE, PLANE_SIZE , 4, 4 )
		plane2.x = PLANES_POSITION.x
		plane2.y = PLANES_POSITION.y+PLANE_SIZE*0.5
		plane2.z = PLANES_POSITION.z+PLANE_SIZE*0.5
		scene.addChild(plane2)
		var p3d2:Plane3D = new Plane3D(new Number3D(0,0,1), new Number3D(plane2.x, plane2.y, plane2.z))
		colorSpot21 = new ColorSpotCaster(p3d2, Sprite(MovieMaterial(plane2.material).movie), 0x00ff00, 200, 200)
		colorSpot22 = new ColorSpotCaster(p3d2, Sprite(MovieMaterial(plane2.material).movie), 0x0000ff, 200, 200)
		colorSpot23 = new ColorSpotCaster(p3d2, Sprite(MovieMaterial(plane2.material).movie), 0xff0000, 200, 200)
		
		var wallBmp3:Bitmap = new wallBitmap() as Bitmap;
		var wallSprite3:Sprite  = new Sprite()
		wallSprite3.addChild(wallBmp3)
		var planeMat3:MovieMaterial = new MovieMaterial(wallSprite3, false, true, false, new Rectangle(0,0, PLANE_SIZE, PLANE_SIZE) );
		plane3 = new Plane(planeMat3, PLANE_SIZE, PLANE_SIZE , 4, 4 )
		plane3.rotationY = -90;
		plane3.x = PLANES_POSITION.x-PLANE_SIZE*0.5
		plane3.y = PLANES_POSITION.y+PLANE_SIZE*0.5
		plane3.z = PLANES_POSITION.z
		scene.addChild(plane3)
		var p3d3:Plane3D = new Plane3D(new Number3D(1,0,0), new Number3D(plane3.x, plane3.y, plane3.z))
		colorSpot31 = new ColorSpotCaster(p3d3, Sprite(MovieMaterial(plane3.material).movie), 0x00ff00, 200, 200)
		colorSpot32 = new ColorSpotCaster(p3d3, Sprite(MovieMaterial(plane3.material).movie), 0x0000ff, 200, 200)
		colorSpot33 = new ColorSpotCaster(p3d3, Sprite(MovieMaterial(plane3.material).movie), 0xff0000, 200, 200)
		
	}

	private function apply3DToPhy(pv3DObject:*, wowObject:*):void {
		pv3DObject.x = wowObject.px;
		pv3DObject.y = wowObject.py;
		pv3DObject.z = wowObject.pz;
	}
	
	private function rotateCamera():void
	{
		if (isDragging && mouseX < 600)
		{
			camera.orbit(stage.mouseX - stage.stageWidth/2, stage.mouseY - stage.stageHeight/2, true, plane1);
		}
	}
	
	public function addListeners():void {
		addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		stage.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler);
		stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
	}
	/*
	 * LISTENERS
	 * 
	 */
	
	public function enterFrameHandler(event:Event):void {
		singleRender();
		rotateCamera();
		wow.step();
		for (var i:int = 0; i < wowObjects.length; i++) 
		{
			apply3DToPhy(pv3dObjects[i], wowObjects[i])			
		}
		
		var relativeSpherePosition1:Number3D = new Number3D(colorSphere1.x-(plane1.x-PLANE_SIZE*0.5), colorSphere1.y-(plane2.y-PLANE_SIZE*0.5), colorSphere1.z-(plane3.z-PLANE_SIZE*0.5));
		var relativeSpherePosition2:Number3D = new Number3D(colorSphere2.x-(plane1.x-PLANE_SIZE*0.5), colorSphere2.y-(plane2.y-PLANE_SIZE*0.5), colorSphere2.z-(plane3.z-PLANE_SIZE*0.5));
		var relativeSpherePosition3:Number3D = new Number3D(colorSphere3.x-(plane1.x-PLANE_SIZE*0.5), colorSphere3.y-(plane2.y-PLANE_SIZE*0.5), colorSphere3.z-(plane3.z-PLANE_SIZE*0.5));
		
		colorSpot11.updateSpotPositions(relativeSpherePosition1, PLANE_SIZE, colorSphere1.distanceTo(plane1));
		colorSpot21.updateSpotPositions(relativeSpherePosition1, PLANE_SIZE, colorSphere1.distanceTo(plane2));
		colorSpot31.updateSpotPositions(relativeSpherePosition1, PLANE_SIZE, colorSphere1.distanceTo(plane3));
		
		colorSpot12.updateSpotPositions(relativeSpherePosition2, PLANE_SIZE, colorSphere2.distanceTo(plane1));
		colorSpot22.updateSpotPositions(relativeSpherePosition2, PLANE_SIZE, colorSphere2.distanceTo(plane2));
		colorSpot32.updateSpotPositions(relativeSpherePosition2, PLANE_SIZE, colorSphere2.distanceTo(plane3));			
		
		colorSpot13.updateSpotPositions(relativeSpherePosition3, PLANE_SIZE, colorSphere3..distanceTo(plane1));
		colorSpot23.updateSpotPositions(relativeSpherePosition3, PLANE_SIZE, colorSphere3.distanceTo(plane2));
		colorSpot33.updateSpotPositions(relativeSpherePosition3, PLANE_SIZE, colorSphere3.distanceTo(plane3));	
	}
	
	public function onPressHandler(event:MouseEvent):void {
		isDragging = true;
		for (var i:int = 0; i < wowObjects.length; i++) 
		{
			wowObjects[i].addForce(new WVector(Math.random()*20, Math.random()*20, Math.random()*20))
		}
	}
	public function onMouseUpHandler(event:MouseEvent):void {
		isDragging = false;
	}
}
}